import { NavBar, InfiniteScroll, Popup } from 'antd-mobile'
import { useHistory, useParams } from 'react-router-dom'
import classNames from 'classnames'
import styles from './index.module.scss'

import Icon from '@/components/Icon'
import CommentItem from './components/CommentItem'
import CommentFooter from './components/CommentFooter'
import { useEffect, useRef, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import {
  followAuthor,
  getAllComment,
  getArticleInfo,
  publishContent,
} from '@/store/actions/article'
import { RootState } from '@/types/store'

// 用于清理dom字符串中的不安全的元素
import DOMPurify from 'dompurify'

// 代码高亮
import hljs from 'highlight.js'
// 导入代码高亮样式
import 'highlight.js/styles/rainbow.css'
import NoComment from './components/NoComment'
import CommentInput from './components/CommentInput'
import CommentReply from './components/CommentReply'
import { Comment } from '@/types/data'

const Article = () => {
  const history = useHistory()
  const params = useParams<{ id: string }>()
  // console.log(params.id)

  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getArticleInfo(params.id))
  }, [dispatch, params.id])

  const { info } = useSelector((state: RootState) => state.article)

  useEffect(() => {
    // 配置 highlight.js
    hljs.configure({ ignoreUnescapedHTML: true })

    // 高亮元素
    // hljs.highlightElement(元素)

    // 自己手动获取页面中所有code元素 进行高亮
    document.querySelectorAll('.dg-html pre code').forEach((el) => {
      hljs.highlightElement(el as HTMLElement)
    })
  }, [])

  const wrapperRef = useRef<HTMLDivElement>(null) // 容器ref
  const authorRef = useRef<HTMLDivElement>(null) // 原来的作者信息盒子

  useEffect(() => {
    const wrapperDom = wrapperRef.current!
    const authorDom = authorRef.current!

    function onScroll() {
      // 获取元素的大小及其相对于视口的位置 信息对象
      const res = authorDom.getBoundingClientRect()
      // console.log(res)
      // if (res.top <= 0) {
      //   // 可以展示顶部作者信息了
      //   setShowAuthor(true)
      // } else {
      //   setShowAuthor(false)
      // }

      setShowAuthor(res.top <= 0)
    }

    wrapperDom.addEventListener('scroll', onScroll)

    return () => {
      wrapperDom.removeEventListener('scroll', onScroll)
    }
  }, [])

  const [showAuthor, setShowAuthor] = useState(false) // 控制顶部作者信息的展示

  // 获取文章评论
  useEffect(() => {
    dispatch(getAllComment(params.id))
  }, [dispatch, params.id])

  const { comment } = useSelector((state: RootState) => state.article)

  const followAuthorFn = () => {
    dispatch(followAuthor(info.aut_id, info.is_followed))
  }

  const commentRef = useRef<HTMLDivElement>(null)

  const [visible, setVisible] = useState(false) // 控制文章评论
  const [visible2, setVisible2] = useState(false) // 控制回复评论
  const [activeComm, setActiveCom] = useState<Comment>({} as Comment) // 记录当前回复的评论信息对象

  const renderArticle = () => {
    // 文章详情
    return (
      // 整个滚动容器
      <div className="wrapper" ref={wrapperRef}>
        {/* 正文部分 */}
        <div className="article-wrapper">
          <div className="header">
            <h1 className="title">{info.title}</h1>

            <div className="info">
              <span>{info.pubdate}</span>
              <span>{info.read_count} 阅读</span>
              <span>{info.comm_count} 评论</span>
            </div>

            {/* 本身的作者信息div */}
            <div className="author" ref={authorRef}>
              <img src={info.aut_photo} alt="" />
              <span className="name">{info.aut_name}</span>
              <span
                className={classNames(
                  'follow',
                  info.is_followed ? 'followed' : ''
                )}
                onClick={followAuthorFn}
              >
                {info.is_followed ? '已关注' : '关注'}
              </span>
            </div>
          </div>

          <div className="content">
            <div
              className="content-html dg-html"
              dangerouslySetInnerHTML={{
                __html: DOMPurify.sanitize(info.content || ''),
              }}
            />
            <div className="date">发布文章时间：{info.pubdate}</div>
          </div>
        </div>

        {/* 评论部分 */}
        <div className="comment" ref={commentRef}>
          <div className="comment-header">
            <span>全部评论（{info.comm_count}）</span>
            <span>{info.like_count} 点赞</span>
          </div>

          <div className="comment-list">
            {/* 一个评论 */}
            {/* <CommentItem /> */}
            {info.comm_count === 0 ? (
              <NoComment></NoComment>
            ) : (
              comment.results?.map((item) => (
                <CommentItem
                  openPopup2={() => {
                    // 打开弹层
                    setVisible2(true)
                    // 记录当前的评论
                    setActiveCom(item)
                  }}
                  type="normal"
                  key={item.com_id}
                  comment={item}
                />
              ))
            )}

            <InfiniteScroll
              hasMore={comment.end_id !== comment.last_id}
              loadMore={async () => {
                // console.log(1)
                await dispatch(getAllComment(params.id, comment.last_id))
              }}
            />
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className={styles.root}>
      <div className="root-wrapper">
        {/* 导航栏 */}
        <NavBar
          onBack={() => history.go(-1)}
          right={
            <span>
              <Icon name="icongengduo" />
            </span>
          }
        >
          {showAuthor && (
            <div className="nav-author">
              <img src={info.aut_photo} alt="" />
              <span className="name">{info.aut_name}</span>
              <span
                className={classNames(
                  'follow',
                  info.is_followed ? 'followed' : ''
                )}
                onClick={followAuthorFn}
              >
                {info.is_followed ? '已关注' : '关注'}
              </span>
            </div>
          )}
        </NavBar>

        {/* 文章详情和评论 */}
        {renderArticle()}

        {/* 底部评论栏 */}
        <CommentFooter
          info={info}
          scrollFn={() => {
            // console.log('我要滚动到评论区。。。')
            // commentRef.current!.????
            // wrapperRef.current!.scrollTop =
            //   commentRef.current!.getBoundingClientRect().top
            // wrapperRef.current!.scrollTop = commentRef.current!.offsetTop - 40
            const commentDom = commentRef.current!
            const wrapperDom = wrapperRef.current!

            if (wrapperDom.scrollTop === commentDom.offsetTop - 40) {
              wrapperDom.scrollTop = 0
            } else {
              wrapperDom.scrollTop = commentDom.offsetTop - 40
            }
          }}
          openPopup={() => {
            setVisible(true)
          }}
        />

        {/* 评论文章的弹层 */}
        <Popup
          visible={visible}
          position="bottom"
          destroyOnClose
          bodyStyle={{ height: '100vh' }}
        >
          <CommentInput
            closePopup={() => {
              setVisible(false)
            }}
            publish={async (val: string) => {
              // console.log(val, 111)
              // 在这里发表评论（子组件永远只收集数据）
              // 评论内容 val
              // 文章id params.id
              await dispatch(publishContent(val, params.id))
              await dispatch(getArticleInfo(params.id)) // 获取文章详情
              setVisible(false)
            }}
          ></CommentInput>
        </Popup>

        {/* 回复评论的弹层 */}
        <Popup
          visible={visible2}
          position="right"
          destroyOnClose
          bodyStyle={{ width: '100vw' }}
          afterClose={() => {
            // 完全关闭后触发（一定是组件卸载了。。。）

            // 清空当前评论信息对象
            setActiveCom({} as Comment)
          }}
        >
          <CommentReply
            closePopup2={() => {
              // 关闭弹层（卸载组件）
              setVisible2(false)
            }}
            comment={activeComm}
          ></CommentReply>
        </Popup>
      </div>
    </div>
  )
}

export default Article
